/*==============================================================================
TCC - Aplicativo Wtcar

@file - Wtcar.cpp
==============================================================================*/


#include "Wtcar.h"

//Objeto para receber atualização callbacks do QCAR
//----------------------------------------------------------------------------
class Wtcar_UpdateCallback : public QCAR::UpdateCallback {

	virtual void QCAR_onUpdate(QCAR::State& state){

		//Pega o image tracker
		QCAR::TrackerManager& trackerManager = QCAR::TrackerManager::getInstance();
		QCAR::ImageTracker* imageTracker = static_cast<QCAR::ImageTracker*>(trackerManager.getTracker(QCAR::Tracker::IMAGE_TRACKER));

		//localizador do target
		QCAR::TargetFinder* finder = imageTracker->getTargetFinder();

		//Verifica se há novos resultados disponíveis
		const int statusCode = finder->updateSearchResults();

		if(statusCode < 0){
			//mostrar mensagem de erro
		}else if (statusCode == QCAR::TargetFinder::UPDATE_RESULTS_AVAILABLE){

			//Processa os novos resultados encontrados
			 if (finder->getResultCount() > 0){

				 const QCAR::TargetSearchResult* result = finder->getResult(0);

				 //Verifica se esta meta é adequado para rastreamento:
				 if (result->getTrackingRating() > 0){

					 //cria um novo trackable do resultado
					 QCAR::Trackable* newTrackable = finder->enableTracking(*result);
					 if (newTrackable != 0){
						 //LOG(Trackable '%s' com classificacao '%d',newTrackable->getName(), result->getTrackingRating())

						 //verifica se o target mudou
						 //LOG ("Comparando os target. Id target Atual: '%s' | Id ultimo target: '%s'",result->getUniqueTargetId(), lastTargetId);
						 if (strcmp(result->getUniqueTargetId(), lastTargetId) != 0){
							 //se mudou, deve recarregar a textura
							 //precisa ser gerado novamente no Java
							 deleteCurrentProductTexture = true;

							 //inicia o estado de carregamento
							 renderState = RS_LOADING;

							 //Copia o metadata do novo target
							 snprintf(targetMetadata, CONTENT_MAX, "%s", result->getMetaData());

							 //Chama o método Java para a textura atual
							 createProductTexture(targetMetadata);
						 }else{
							 renderState = RS_NORMAL;
						 }

						 // Inicializar os quadros --- 2D
						 pthread_mutex_lock(&framesToSkipMutex);
						 framesToSkipBeforeRenderingTransition = 10;
						 pthread_mutex_unlock(&framesToSkipMutex);

						//Inicializa os estado das variáveis
						 showAnimation3Dto2D = true;
						 trackingStarted = false;

						 //atualiza o valor do target atual com o novo target encontrado
						 pthread_mutex_lock(&lastTargetIdMutex);
						 strcpy(lastTargetId, result->getUniqueTargetId());
						 pthread_mutex_unlock(&lastTargetIdMutex);

						 enterContentMode();
					 }else{
						 //LOG("Failed to create new trackable.");
					 }
				 }
			 }
		}
	}
};
Wtcar_UpdateCallback updateCallback;


// ----------------------------------------------------------------------------
// Transição da aplicação para o modo de conteúdo
// ----------------------------------------------------------------------------
void
enterContentMode()
{
    // Verifica se o indicador JNI estão configurados corretamente
    JNIEnv* env = 0;
    if (javaVM != 0 && enterContentModeID != 0 && activityObj != 0
            && javaVM->GetEnv((void**)&env, JNI_VERSION_1_4) == JNI_OK)
    {
        env->CallVoidMethod(activityObj, enterContentModeID);
    }
}

// ----------------------------------------------------------------------------
// Funções nativa chamada no Java
// ----------------------------------------------------------------------------


//Define a variável de orientação da activity
//-----------------------------------------------------------------------------
JNIEXPORT void JNICALL
Java_br_com_tcc_activity_CameraActivity_setActivityModoRetrato(JNIEnv *, jobject, jboolean isRetrato)
{
	isActivityModoRetrato = isRetrato;
}


//Inicializar o tracker
//-----------------------------------------------------------------------------
JNIEXPORT jboolean JNICALL
Java_br_com_tcc_activity_CameraActivity_iniciarTracker(JNIEnv *, jobject)
{
	// Inicialiazando image tracker:
	QCAR::TrackerManager& trackerManager = QCAR::TrackerManager::getInstance();
	QCAR::Tracker* tracker = trackerManager.initTracker(QCAR::Tracker::IMAGE_TRACKER);
	if (tracker == NULL)
	 {
	     LOG("Falha ao inicializar o ImageTracker.");
	     return JNI_FALSE;
	 }

	    LOG("ImageTracker inciado com sucesso!");
	    return JNI_TRUE;
}


//Inicializar a renderização
//-----------------------------------------------------------------------------

JNIEXPORT void JNICALL
Java_br_com_tcc_view_WtcarRenderer_iniciarRenderer(JNIEnv *, jobject)
{
	// Define clear color
	glClearColor(0.0f, 0.0f, 0.0f, QCAR::requiresAlpha() ? 0.0f : 1.0f);
}

// Inicializa aplicação nativa
// ----------------------------------------------------------------------------
JNIEXPORT void JNICALL
Java_br_com_tcc_activity_CameraActivity_iniciarAplicacaoNativa(JNIEnv* env, jobject obj, jint largura, jint altura){

	//Armazena as dimensões da tela
	larguraDaTela = largura;
	alturaDaTela = altura;

	//Indentificador da activity
	jclass activityClass = env->GetObjectClass(obj);


	// Registra a função callback que é chamada toda vez que um ciclo de monitoramento
	//termina e um novo estado AR é disponível
	QCAR::registerCallback(&updateCallback);

	// tamanho da tela
	QCAR::Vec2F screenSize;
	screenSize.data[0] = (float) larguraDaTela;
	screenSize.data[1] = (float) alturaDaTela;

	//Inicializar método para mostrar mensagens de erro ---
	//LOG("Function showErrorMessage() not found.");
	//O método é criado no Java -- e não é necessário agora

	// Inicializar os métodos Java chamados no código nativo
	createProductTextureID = env->GetMethodID(activityClass, "createProductTexture", "(Ljava/lang/String;)V");
	getProductTextureID = env->GetMethodID(activityClass, "getProductTexture", "()Lcom/qualcomm/QCARSamples/CloudRecognition/Texture;");
	showStatusBarID = env->GetMethodID(activityClass, "showStatusBar", "()V");
	hideStatusBarID = env->GetMethodID(activityClass, "hideStatusBar", "()V");
	setStatusBarTextID = env->GetMethodID(activityClass, "setStatusBarText", "(Ljava/lang/String;)V");
	enterContentModeID = env->GetMethodID(activityClass,"enterContentMode", "()V");

	activityObj = env->NewGlobalRef(obj);

	// Resete nas variáveis globais
	initStateVariables();
}

// Inicializa o estado das variáveis
// ----------------------------------------------------------------------------
void
initStateVariables()
{
    // Inicializar variáveis ​​de estado de transição
    renderState = RS_SCANNING;

    // Initialize textures state variables
    //productTexture = 0;

    pthread_mutex_lock(&lastTargetIdMutex);
    lastTargetId[0] = '\0';
    pthread_mutex_unlock(&lastTargetIdMutex);

    // Initialize state values
    scanningMode = true;
    isShowing2DOverlay = false;
    startTransition3Dto2D = false;
}


// ----------------------------------------------------------------------------
/**Chama o método Java para iniciar o carregamento da textura*/
// ----------------------------------------------------------------------------
void
createProductTexture(const char* targetMetadata)
{
    // Check that the JNI handles are setup correctly:
    JNIEnv* env = 0;

    if (javaVM != 0 && createProductTextureID != 0 && activityObj != 0
            && javaVM->GetEnv((void**)&env, JNI_VERSION_1_4) == JNI_OK)
    {

        env->CallVoidMethod(activityObj, createProductTextureID, env->NewStringUTF(targetMetadata));

    }
}


#ifdef __cplusplus
}

#endif

